#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
#include<sys/wait.h>

//void func()
//{
//  exit(-1);
//}
//int main()
//{
//  printf("hello linux\n");
//  return 1;
//}

//int main()
//{
//    //int* p = NULL;
//    while(1)
//    {
//      printf("I am a process,pid:%d,ppid:%d\n",getpid(),getppid());
//    sleep(1);
//    }
//    //*p = 100;// 对空指针进行解引用
//    return 0;
//}

//int main( void )
//{
//  pid_t id;
//  printf("Before: pid is %d\n", getpid());
//  // id = fork 先创建进程并赋值，返回值为-1则创建失败，直接退出
//  if ( (id=fork()) == -1 )perror("fork()"),exit(1);
//  printf("After:pid is %d, fork return %d\n", getpid(), id);
//  sleep(1);
//  return 0;
//}

#include "task.h"

typedef void(*func_t)();// 重命名函数指针

#define N 3
func_t tasks[N] = {NULL};

void LoadTask()
{
  tasks[0] = PrintLog;
  tasks[1] = DownLoad;
  tasks[2] = MysqlDataSync;
}

void HandlerTask()
{
  for(int i=0;i<N;i++)
  {
    tasks[i]();
  }
}

void DoOtherThing()
{
  HandlerTask();
}

void RunChild()
{
  int cnt = 5;
  //int* p = NULL;
  while(cnt)
  {
    printf("I am child process,pid:%d,ppid:%d\n",getpid(),getppid());
    sleep(1);
    cnt--;
    //*p = 100;
  }
}

int main()
{
  printf("I am father process,pid:%d,ppid:%d\n",getpid(),getppid());
  pid_t id = fork();
  if(id == 0)
  {
    // child 
    RunChild();  
    printf("child quit...\n");
    exit(123);
  }
  
  // father
  LoadTask();
  while(1)
  {
    int status = 0;
    pid_t rid = waitpid(id,&status,WNOHANG); // non block
    // 子进程还没退出
    if(rid == 0)
    {
      usleep(100000);
      printf("child is running,father check out next\n");
      DoOtherThing();
    }
    // 子进程退出且等待成功
    else if(rid > 0)
    {
      if(WIFEXITED(status))
      {
         printf("child quit success, child exit code : %d\n", WEXITSTATUS(status));
      }
      else 
      {
         printf("child quit unnormal!\n");
      }
      break;
    }
    // 等待失败
    else 
    {
      printf("wait failed!\n");
      break;
    }
  }
  
  //sleep(6);
  //// father
  //int status = 0;
  //pid_t rid = waitpid(id,&status,0);
  //if(rid > 0)
  //{
  //  if(WIFEXITED(status))
  //    printf("child quit success,child exit code:%d\n",WEXITSTATUS(status));
  //  else 
  //    printf("child quit unnormal!\n");
  //  printf("wait success\n");
  //}
  //else 
  //{
  //  printf("wait failed!\n");
  //}
  //sleep(3);
  //printf("father quit, status: %d, child quit code : %d, child quit signal: %d\n", status, (status>>8)&0xFF, status & 0x7F);
  return 0;
}

//int main()
//{
//  printf("I am a father process,pid:%d,ppid:%d\n",getpid(),getppid());
//  pid_t id = fork();
//  if(id == 0)
//  {
//    RunChild();
//    printf("child quit...\n");
//    exit(123);
//  }
//  sleep(6);
//  // father
//  //pid_t rid = wait(NULL);
//  //sleep(2);
//  //printf("father quit...\n");
//  //pid_t rid = waitpid(-1,NULL,0);
//  
//  int status = 0;
//  //pid_t rid = waitpid(-1,&status,0);
//  pid_t rid = waitpid(id,&status,0);
//  if(rid > 0)
//  {
//    printf("wait sucess,pid:%d\n",rid);
//  }
//  else
//  {
//    printf("wait failed!\n");
//  }
//  //int status = 0;
//  //pid_t rid = waitpid(-1,&status,0);
//  sleep(2);
//  //printf("father quit...\n");
//  printf("father quit...,child quit code :%d,child signal code:%d\n",(status>>8)&0xFF,status & 0x7F);
//  return 0;
//}

//int main()
//{
//  printf("hello linux");
//  sleep(2);
//  _exit(1);
//}

// 枚举常量
//enum 
//{
//  Sucess = 0,
//  Div_zero,
//  Mod_zero,
//};
//int exit_code = Sucess;
//
//const char* CodeToErrString(int code)
//{
//  switch(code)
//  {
//    case Sucess:
//      return "Sucess";
//    case Div_zero:
//      return "Div_zero";
//    case Mod_zero:
//      return "Mod_zero";
//    default:
//      return "Unkown error";
//  }
//}
//int Div(int x,int y)
//{
//  if(y==0)
//  {
//   // y等于0则设置退出码
//   exit_code = Div_zero;
//   return -1;
//  }
//  else 
//  {
//    return x/y;
//    //_exit(12);
//  }
//}
//int main()
//{
//  //int* p = NULL;
//  //while(1)
//  //{
//  //  printf("I am a process,pid:%d\n",getpid());
//  //  sleep(1);
//  //  //var*p = 100;
//  //  //exit(10);
//  //}
//  int result = Div(10,100);
//  printf("result:%d [%s]\n",result,CodeToErrString(exit_code));
//  result = Div(10,0);
//  printf("result:%d [%s]\n",result,CodeToErrString(exit_code));
//  //for(int i=0;i<255;i++)
//  //{
//  //  printf("%d :%s\n",i,strerror(i));
//  //}
//  //printf("I am a process,pid:%d,ppid:%d\n",getpid(),getppid());
//  return 0;
//}
